#include "course_manager.h"
#include "database.h"
#include <sstream>

CourseManager::CourseManager(Database* db) : db_(db) {}

std::vector<Course> CourseManager::getAllCourses() {
    std::vector<Course> courses;
    std::string sql = R"(
        SELECT c.id, c.course_code, c.course_name, c.teacher_id, t.name as teacher_name,
               c.description, c.credits, c.max_students, c.current_students,
               c.semester, c.classroom, c.schedule, c.status
        FROM courses c
        LEFT JOIN teachers t ON c.teacher_id = t.id
        ORDER BY c.created_at DESC
    )";

    std::cout << "getAllCourses - Executing SQL: " << sql << std::endl;
    auto result = db_->query(sql);
    std::cout << "getAllCourses - Query result: " << (result ? "success" : "failed") << std::endl;

    if (!result) {
        std::cout << "getAllCourses - No result from query" << std::endl;
        return courses;
    }

    MYSQL_ROW row;
    while ((row = mysql_fetch_row(result.get()))) {
        Course course;
        course.id = std::stoi(row[0]);
        course.course_code = row[1] ? row[1] : "";
        course.course_name = row[2] ? row[2] : "";
        course.teacher_id = row[3] ? std::stoi(row[3]) : 0;
        course.teacher_name = row[4] ? row[4] : "";
        course.description = row[5] ? row[5] : "";
        course.credits = std::stoi(row[6]);
        course.max_students = std::stoi(row[7]);
        course.current_students = std::stoi(row[8]);
        course.semester = row[9] ? row[9] : "";
        course.classroom = row[10] ? row[10] : "";
        course.schedule = row[11] ? row[11] : "";
        course.status = row[12] ? row[12] : "";
        courses.push_back(course);
    }

    return courses;
}

std::optional<Course> CourseManager::getCourseById(int courseId) {
    std::stringstream ss;
    ss << "SELECT c.id, c.course_code, c.course_name, c.teacher_id, t.name as teacher_name, "
       << "c.description, c.credits, c.max_students, c.current_students, "
       << "c.semester, c.classroom, c.schedule, c.status "
       << "FROM courses c LEFT JOIN teachers t ON c.teacher_id = t.id WHERE c.id = " << courseId;

    auto result = db_->query(ss.str());
    if (!result) {
        return std::nullopt;
    }

    MYSQL_ROW row = mysql_fetch_row(result.get());
    if (!row) {
        return std::nullopt;
    }

    Course course;
    course.id = std::stoi(row[0]);
    course.course_code = row[1] ? row[1] : "";
    course.course_name = row[2] ? row[2] : "";
    course.teacher_id = row[3] ? std::stoi(row[3]) : 0;
    course.teacher_name = row[4] ? row[4] : "";
    course.description = row[5] ? row[5] : "";
    course.credits = std::stoi(row[6]);
    course.max_students = std::stoi(row[7]);
    course.current_students = std::stoi(row[8]);
    course.semester = row[9] ? row[9] : "";
    course.classroom = row[10] ? row[10] : "";
    course.schedule = row[11] ? row[11] : "";
    course.status = row[12] ? row[12] : "";

    return course;
}

std::vector<Course> CourseManager::searchCourses(const std::string& keyword) {
    std::string escapedKeyword = db_->escapeString(keyword);
    std::string sql = "SELECT c.id, c.course_code, c.course_name, c.teacher_id, t.name as teacher_name, "
                     "c.description, c.credits, c.max_students, c.current_students, "
                     "c.semester, c.classroom, c.schedule, c.status "
                     "FROM courses c LEFT JOIN teachers t ON c.teacher_id = t.id "
                     "WHERE c.course_name LIKE '%" + escapedKeyword + "%' "
                     "OR c.course_code LIKE '%" + escapedKeyword + "%' "
                     "OR c.description LIKE '%" + escapedKeyword + "%' "
                     "ORDER BY c.created_at DESC";

    std::vector<Course> courses;
    auto result = db_->query(sql);
    if (!result) {
        return courses;
    }

    MYSQL_ROW row;
    while ((row = mysql_fetch_row(result.get()))) {
        Course course;
        course.id = std::stoi(row[0]);
        course.course_code = row[1] ? row[1] : "";
        course.course_name = row[2] ? row[2] : "";
        course.teacher_id = row[3] ? std::stoi(row[3]) : 0;
        course.teacher_name = row[4] ? row[4] : "";
        course.description = row[5] ? row[5] : "";
        course.credits = std::stoi(row[6]);
        course.max_students = std::stoi(row[7]);
        course.current_students = std::stoi(row[8]);
        course.semester = row[9] ? row[9] : "";
        course.classroom = row[10] ? row[10] : "";
        course.schedule = row[11] ? row[11] : "";
        course.status = row[12] ? row[12] : "";
        courses.push_back(course);
    }

    return courses;
}

bool CourseManager::selectCourse(int studentId, int courseId) {
    // 检查课程是否可用
    if (!isCourseAvailable(courseId)) {
        return false;
    }

    // 检查学生是否已经选了这门课
    if (hasStudentSelectedCourse(studentId, courseId)) {
        return false;
    }

    std::stringstream ss;
    ss << "INSERT INTO course_selections (student_id, course_id) VALUES (" << studentId << ", " << courseId << ")";

    if (db_->execute(ss.str())) {
        // 更新课程当前学生数
        ss.str("");
        ss << "UPDATE courses SET current_students = current_students + 1 WHERE id = " << courseId;
        db_->execute(ss.str());

        // 检查是否达到最大人数
        auto course = getCourseById(courseId);
        if (course && course->current_students + 1 >= course->max_students) {
            ss.str("");
            ss << "UPDATE courses SET status = '已满' WHERE id = " << courseId;
            db_->execute(ss.str());
        }

        return true;
    }

    return false;
}

bool CourseManager::dropCourse(int studentId, int courseId) {
    std::stringstream ss;
    ss << "UPDATE course_selections SET status = '退选' WHERE student_id = " << studentId
       << " AND course_id = " << courseId << " AND status = '已选'";

    if (db_->execute(ss.str())) {
        // 更新课程当前学生数
        ss.str("");
        ss << "UPDATE courses SET current_students = GREATEST(current_students - 1, 0) WHERE id = " << courseId;
        db_->execute(ss.str());

        // 更新课程状态
        ss.str("");
        ss << "UPDATE courses SET status = '可选' WHERE id = " << courseId << " AND status = '已满'";
        db_->execute(ss.str());

        return true;
    }

    return false;
}

std::vector<Course> CourseManager::getStudentCourses(int studentId) {
    std::vector<Course> courses;
    std::stringstream ss;
    ss << R"(
        SELECT c.id, c.course_code, c.course_name, c.teacher_id, t.name as teacher_name,
               c.description, c.credits, c.max_students, c.current_students,
               c.semester, c.classroom, c.schedule, c.status
        FROM courses c
        LEFT JOIN teachers t ON c.teacher_id = t.id
        INNER JOIN course_selections cs ON c.id = cs.course_id
        WHERE cs.student_id = )" << studentId << " AND cs.status = '已选'";

    auto result = db_->query(ss.str());
    if (!result) {
        return courses;
    }

    MYSQL_ROW row;
    while ((row = mysql_fetch_row(result.get()))) {
        Course course;
        course.id = std::stoi(row[0]);
        course.course_code = row[1] ? row[1] : "";
        course.course_name = row[2] ? row[2] : "";
        course.teacher_id = row[3] ? std::stoi(row[3]) : 0;
        course.teacher_name = row[4] ? row[4] : "";
        course.description = row[5] ? row[5] : "";
        course.credits = std::stoi(row[6]);
        course.max_students = std::stoi(row[7]);
        course.current_students = std::stoi(row[8]);
        course.semester = row[9] ? row[9] : "";
        course.classroom = row[10] ? row[10] : "";
        course.schedule = row[11] ? row[11] : "";
        course.status = row[12] ? row[12] : "";
        courses.push_back(course);
    }

    return courses;
}

std::optional<Student> CourseManager::getStudentByUserId(int userId) {
    std::stringstream ss;
    ss << "SELECT id, user_id, student_id, name, gender, class_name, email, phone "
       << "FROM students WHERE user_id = " << userId;

    auto result = db_->query(ss.str());
    if (!result) {
        return std::nullopt;
    }

    MYSQL_ROW row = mysql_fetch_row(result.get());
    if (!row) {
        return std::nullopt;
    }

    Student student;
    student.id = std::stoi(row[0]);
    student.user_id = std::stoi(row[1]);
    student.student_id = row[2] ? row[2] : "";
    student.name = row[3] ? row[3] : "";
    student.gender = row[4] ? row[4] : "";
    student.class_name = row[5] ? row[5] : "";
    student.email = row[6] ? row[6] : "";
    student.phone = row[7] ? row[7] : "";

    return student;
}

bool CourseManager::isCourseAvailable(int courseId) {
    auto course = getCourseById(courseId);
    if (!course) {
        return false;
    }

    return course->status == "可选" && course->current_students < course->max_students;
}

bool CourseManager::hasStudentSelectedCourse(int studentId, int courseId) {
    std::stringstream ss;
    ss << "SELECT COUNT(*) FROM course_selections WHERE student_id = " << studentId
       << " AND course_id = " << courseId << " AND status = '已选'";

    auto result = db_->query(ss.str());
    if (!result) {
        return false;
    }

    MYSQL_ROW row = mysql_fetch_row(result.get());
    if (!row) {
        return false;
    }

    return std::stoi(row[0]) > 0;
}
